package main

import (
	"context"
	"fmt"
	"os"
	"os/signal"

	"net/http"
	"time"

	"golang.org/x/sync/errgroup"
)

type Engine struct {
}

func (engine *Engine) ServeHTTP(w http.ResponseWriter, req *http.Request) {
	switch req.URL.Path {
	case "/test":
		fmt.Fprintf(w, "test web handler = %q\n", req.URL.Path)
	default:
		fmt.Fprintf(w, "404 not found = %q\n", req.URL.Path)
	}
}

func StartHttpServe() error {
	engine := new(Engine)
	serve = &http.Server{
		Addr:           ":8082",
		Handler:        engine,
		ReadTimeout:    10 * time.Second,
		WriteTimeout:   10 * time.Second,
		MaxHeaderBytes: 1 << 20,
	}
	if err := serve.ListenAndServe(); err != nil {
		return err
	}
	return nil
}

func StopHttpServe() error {
	for {
		select {
		case <-ctrlChan:
			//确保在关闭的时候还在执行的多个请求优雅退出
			ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
			defer cancel()
			err := serve.Shutdown(ctx)
			return err
		}
	}
}

var ctrlChan chan os.Signal
var serve *http.Server

func main() {
	group := new(errgroup.Group)
	ctrlChan = make(chan os.Signal)
	signal.Notify(ctrlChan, os.Interrupt, os.Kill)
	group.Go(StartHttpServe)

	group.Go(StopHttpServe)

	err := group.Wait()
	if err != nil {
		fmt.Println("error:", err)
	}
}
